from iutk import *
from functions import *
from tkinter.filedialog import askopenfilename, asksaveasfilename

''' on définit les variables de bases '''
largeurMenu = 500
hauteurMenu = 500
boutonsMenu = initialiserBoutonMenu(largeurMenu, hauteurMenu)


''' Zone de taille strictement fixe '''
zoneBouton = 150

''' on crée la fenêtre de dialogue '''
creeFenetre(largeurMenu, hauteurMenu+zoneBouton)

while True:

    ### BOUCLE PRINCIPALE : MENU SOKOBAN ###

    texte(largeurMenu//2-100,10, 'SOKOBAN', 'red')
    texte(10, hauteurMenu+zoneBouton-50, 'Mercier, Pronier', 'black')

    ''' On attend un clic pour connaître le choix '''
    afficherBouton(boutonsMenu)
    miseAJour()
    ev = clic()
    effaceTout()

    ''' on quitte le menu si ev correspond à un bouton '''
    menu = False

    if coordBoutons(boutonsMenu, ev) == 'jouer':

        ## Boucle du jeu ##

        ''' On essaye d'ouvrir une map par le biais de askopenfile.
            En cas d'échec, on retourne au menu grâce au except. '''

        try:
            ''' on choisit la map '''
            nomMap = askopenfilename()
            fichierMap = open(nomMap)

            ''' on la stocke dans une matrice '''
            matriceAll=lectureFichierMap(fichierMap)
            titre=matriceAll[0]
            titre=titre[9:-2]

            highScore=matriceAll[1]

            
            if highScore!="?":
                highScore=int(highScore)
            
            map = matriceAll[2]
            
            ''' on genère la taille de la map par rapport à la fenêtre '''
            definition = largeurMenu//max(len(map[0]), len(map))
            largeurFenetre = len(map[0])*definition
            hauteurFenetre = len(map)*definition

            ''' on crée les emplacements personnage, boutons, clÃ©s et trou '''
            emplacementPerso=initialisationPersonnage(map)
            boutonsJeu = initialiserBoutonJeu(hauteurMenu, largeurMenu)
            lstCle=[0]
            lstTrou=listeTrou(map)
            space=False
            nbCoup=0

            ''' on genère la liste qui contient les informations de undo '''
            resetCoup = [[copierMap(map), copierMatrice(emplacementPerso), copierMatrice(lstCle), copierMatrice(lstTrou)]]
            undoCoup = [[copierMap(map), copierMatrice(emplacementPerso), copierMatrice(lstCle), copierMatrice(lstTrou)]]

            
        except:
            menu = True

        while menu == False:

            ## En jeu ##            

            ''' On est parvenu à ouvrir une map donc la bloucle de jeu commence '''

            rectanglePlein(0, 0, largeurFenetre, hauteurFenetre, 'white')
            afficheTrou(lstTrou, definition)
            afficherMap(map, definition)
            afficherPerso(emplacementPerso, definition)
            afficherGrille(largeurFenetre, hauteurFenetre, definition)
            afficherBouton(boutonsJeu, nbCoup, highScore)
            miseAJour()
            

            ''' On vérifie si on a gagné '''
            if verifGagne(map, lstTrou) == True:
                
                if highScore=="?" or nbCoup<highScore:

                    texteCentre(largeurMenu//2, hauteurMenu//2, 'Record battu !\nVous avez gagné!', 'red')
                    ma_map = matriceAll[3]
                    ma_map=remplacerRecord(ma_map,nbCoup)
                    fichierMap = open(nomMap, 'w')
                    fichierMap.write(ma_map)
                    fichierMap.close()

                else:
                    texteCentre(largeurMenu//2, hauteurMenu//2, 'Gagné!', 'red')
                    
                attenteClic()
                menu = True
                effaceTout()

            else:
                ''' On attent une touche de déplacement ou un clic'''
                ev=attenteEv()

                ''' On gère la possibilité de tirer les blocs spéciaux '''
                if ev == "space" and space == False:
                    space=True
                elif ev=="space" and space==True:
                    space=False

                ''' Si on obtient une des touches de déplacement par ev, on actionne
                    le déplacement du personnage. '''
                
                    
                if ev in ['Up','Down','Right','Left']:
                    
                    direction=ev
                    emplacementAvant=emplacementPerso*1
                    emplacementPerso=deplacementPersonnage(map,direction,emplacementPerso,lstCle)
                    if emplacementAvant!=emplacementPerso:
                        nbCoup+=1
                        undoCoup.append([copierMap(map), copierMatrice(emplacementPerso), copierMatrice(lstCle), copierMatrice(lstTrou)])
                
                    if space==True and procheBlocS(emplacementAvant,map)!=False:
                        listBlocS=procheBlocS(emplacementAvant,map)
                        for bloc in listBlocS:
                            deplacementBlocS(emplacementPerso,emplacementAvant,map,direction,bloc)

            
                ''' Si on a un clic, on cherche à quoi correspond ses coordonnéees '''
                if coordBoutons(boutonsJeu, ev) != 'None':
                    
                    val = coordBoutons(boutonsJeu, ev)

                    ''' L'utilisateur peut quitter le jeu '''
                    if val == 'quit':
                        fermeFenetre()

                    ''' Recommencer la partie '''
                    if val == 'reset':

                        ''' on remet la matrice à zéro '''
                        map = copierMap(resetCoup[0][0])
                        undoCoup=[]

                        ''' on recrée les emplacements personnage, boutons, clées et trou '''
                        emplacementPerso = copierMatrice(resetCoup[0][1])
                        lstCle = copierMatrice(resetCoup[0][2])
                        lstTrou = copierMatrice(resetCoup[0][3])
                        space = False
                        nbCoup=0

                    ''' Retourner au menu '''
                    if val == 'menu':
                        menu = True
                        effaceTout()
                        break

                    ''' Annuler ses coups précédents '''
                    if val == 'undo':

                        
                        try:
                            ''' On supprime le dernier coup enregistrer '''
                            undoCoup.remove(undoCoup[-1])

                            ''' on remet la matrice du coup précédent '''
                            map = copierMap(undoCoup[-1][0])

                            ''' on remet les emplacements personnage, boutons, clés et trou du coup précédent'''
                            emplacementPerso = copierMatrice(undoCoup[-1][1])
                            lstCle = copierMatrice(undoCoup[-1][2])
                            lstTrou = copierMatrice(undoCoup[-1][3])
                            nbCoup-=1
                            
                            
                        except:
                            continue

                effaceTout()

    elif coordBoutons(boutonsMenu, ev) == 'editer':

        definition = 25
        boutonsConfirmation = initialiserBoutonsConfirmation(hauteurMenu, largeurMenu)

        rectanglePlein(0, 0, largeurMenu, hauteurMenu, 'white')
        afficherGrille(largeurMenu, hauteurMenu, definition)
        texte(10, hauteurMenu+zoneBouton//10, 'Taille grille?', 'black')

        miseAJour()    
        validation = False

        while validation not in boutonsConfirmation:

                x,y = clic()
                
                if y >= 0 and y < hauteurMenu:

                    caseX, caseY = tailleTableau(largeurMenu, hauteurMenu, definition, (x,y))
                    effaceTout()

                    rectanglePlein(0, 0, largeurMenu, hauteurMenu, 'white')
                    afficherZone(caseX, caseY, definition)
                    afficherGrille(largeurMenu, hauteurMenu, definition)

                    txt = 'Confirmer une grille de '+str((caseY//definition)+1)+'*'+str((caseX//definition)+1)+' ?'
                    texte(10, hauteurMenu+10, txt, 'black')
                    afficherBouton(boutonsConfirmation)

                    miseAJour()

                else:
                    validation = coordBoutons(boutonsConfirmation, (x,y))

        if validation == 'oui':
            
            effaceTout()

            map = creerMap(caseX//definition, caseY//definition)

            definition = largeurMenu//max(len(map[0]), len(map))
            largeurFenetre = len(map[0])*definition
            hauteurFenetre = len(map)*definition

        elif validation == 'menu':
            menu = True

        elif validation == 'open':
            try:
                nomMap = askopenfilename()
                fichierMap = open(nomMap)

                ''' on la stocke dans une matrice '''
                matriceAll=lectureFichierMap(fichierMap)
                titre=matriceAll[0]
                titre=titre[9:-2]
                highScore=matriceAll[1]
                map = matriceAll[2]

                print(map)

                ''' on genère la taille de la map par rapport à la fenêtre '''
                definition = largeurMenu//max(len(map[0]), len(map))
                largeurFenetre = len(map[0])*definition
                hauteurFenetre = len(map)*definition
            except:
                menu = False

        boutons = initialiserBoutonsEditeur(hauteurMenu, largeurMenu)
        couleur = 'vide'
        effaceTout()

        while menu == False:

            rectanglePlein(0, 0, largeurFenetre, hauteurFenetre, 'white')
            afficherMap(map, definition)
            afficherGrille(largeurFenetre, hauteurFenetre, definition)
            afficherBouton(boutons)
            miseAJour()

            ev=clic()

            if coordBoutons(boutons,ev) != 'None':
                couleur = coordBoutons(boutons, ev)

            elif coordEditeur(ev, largeurFenetre, hauteurFenetre, definition) != 'None':
                x, y = coordEditeur(ev, largeurFenetre, hauteurFenetre, definition)
                if couleur == 'Vide':
                    couleur = ''
                map[x][y] = couleur

            if coordBoutons(boutons, ev) == 'menu':
                menu = True
                effaceTout()
                break

            elif coordBoutons(boutons, ev) == 'quit':
                fermeFenetre()

            elif coordBoutons(boutons, ev) == 'save':
                
                if mapEstJouable(map) == True:
                    try:
                        ma_map = transposerMatriceMap(map)
                        nomMap = asksaveasfilename()
                        fichierMap = open(nomMap, 'w')
                        fichierMap.write(ma_map)
                        fichierMap.close()
                    except:
                        continue

                else:
                    texteCentre(largeurMenu//2, hauteurMenu//2, 'Map non jouable!\nCliquer', 'red')
                    miseAJour()
                    attenteClic()

            elif coordBoutons(boutons, ev) == 'open':
                nomMap = askopenfilename()
                fichierMap = open(nomMap)

                ''' on la stocke dans une matrice '''
                matriceAll=lectureFichierMap(fichierMap)
                titre=matriceAll[0]
                titre=titre[9:-2]
                highScore=matriceAll[1]
                map = matriceAll[2]
                print(map)

                ''' on genère la taille de la map par rapport à la fenêtre '''
                definition = largeurMenu//max(len(map[0]), len(map))
                largeurFenetre = len(map[0])*definition
                hauteurFenetre = len(map)*definition
                

            effaceTout()


fermeFenetre()



